Public Class MyWavelengths

    Public Class WavelengthException
        Inherits Exception

        Public Sub New(ByVal message As String)
            MyBase.New(message)
        End Sub

    End Class

    Private Const NWAVES_DEFAULT As Integer = 21
    Private Const MAX_WAVES As Integer = 90
    Private Const MIN_VALUE As Decimal = 0.38D
    Private Const MAX_VALUE As Decimal = 0.98D
    Private Const START_LAMBDA As Decimal = 0.78D
    Private Const STEP_LAMBDA As Decimal = 0.02D

    Private m_WavelengthList As New List(Of Decimal)
    Private m_UndoWavelengthList As New List(Of Decimal)

    Public Event Changed()

    Public Sub New()
        Me.Resize(NWAVES_DEFAULT)
    End Sub

    Public Sub Add(ByVal value As Decimal)
        If m_WavelengthList.Contains(value) Then
            Throw New WavelengthException(Language.ReadMessages("msgWAVEEXIST"))
        Else
            If Me.Count = MAX_WAVES Then
                Throw New WavelengthException(String.Format(Language.ReadMessages("msgMAXWAVES"), MAX_WAVES))
            ElseIf value < MIN_VALUE OrElse value > MAX_VALUE Then
                Throw New WavelengthException(String.Format(Language.ReadMessages("msgWAVERANGE"), MIN_VALUE, MAX_VALUE))
            Else
                m_WavelengthList.Add(value)
            End If
        End If
        m_WavelengthList.Sort()
        m_WavelengthList.Reverse()
        RaiseEvent Changed()
    End Sub

    Public Sub AddRange(ByVal start As Decimal, ByVal count As Integer, ByVal [step] As Decimal)
        Me.AddRangeValues(start, count, [step])
        RaiseEvent Changed()
    End Sub

    Public Sub ClearUndo()
        m_UndoWavelengthList.Clear()
    End Sub

    Public Function Count() As Integer
        Return m_WavelengthList.Count
    End Function

    Public Property Item(ByVal wavelength As Integer) As Decimal
        Get
            Return m_WavelengthList.Item(wavelength - 1)
        End Get
        Set(ByVal value As Decimal)
            m_WavelengthList.Item(wavelength - 1) = value
        End Set
    End Property

    Public Sub RemoveAt(ByVal wavelength As Integer)
        m_WavelengthList.RemoveAt(wavelength - 1)
        RaiseEvent Changed()
    End Sub

    Public Sub Resize(ByVal count As Integer)
        Me.AddRangeValues(MAX_VALUE, count, STEP_LAMBDA)
    End Sub

    Public Sub SetDefaultValues()
        Me.AddRangeValues(START_LAMBDA, NWAVES_DEFAULT, STEP_LAMBDA)
        RaiseEvent Changed()
    End Sub

    Public Sub SetUndo()
        Me.ClearUndo()
        For intIndex As Integer = 1 To Me.Count
            m_UndoWavelengthList.Add(Me.Item(intIndex))
        Next
    End Sub

    Public Sub Undo()
        m_WavelengthList.Clear()
        For Each decValue As Decimal In m_UndoWavelengthList
            m_WavelengthList.Add(decValue)
        Next
        Me.ClearUndo()
        RaiseEvent Changed()
    End Sub


    Private Sub AddRangeValues(ByVal start As Decimal, ByVal count As Integer, ByVal [step] As Decimal)
        If count <= 0 Then
            Throw New ArgumentException
        Else
            m_WavelengthList.Clear()
            m_WavelengthList.Add(start)
            For intIndex As Integer = 2 To count
                m_WavelengthList.Add(Me.Item(intIndex - 1) - [step])
            Next
        End If
    End Sub

End Class
